#include "fxcc/imgui/Editor.h"
#include "fxcc/core/graph/common/TextureMaps.h"
#include "fxcc/core/graph/common/TextureImporter.h"

using namespace fxcc::graph::common;
using namespace fxcc::imgui;


template<>
bool Editor::Edit<fxcc::graph::common::Texture2DMap>(const std::string& l, fxcc::graph::common::Texture2DMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_Texture2Ds.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_Texture2Ds)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}

	ImGui::Image(e.GetTextureId(), { 100,100 });

	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::TextureCubeMap>(const std::string& l, fxcc::graph::common::TextureCubeMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{
		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_TextureCubes.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_TextureCubes)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}

template<>
bool Editor::Edit<fxcc::graph::common::Texture2DArrayMap>(const std::string& l, fxcc::graph::common::Texture2DArrayMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_Texture2DArrays.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_Texture2DArrays)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::TextureCubeArrayMap>(const std::string& l, fxcc::graph::common::TextureCubeArrayMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_TextureCubeArrays.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_TextureCubeArrays)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::Texture3DMap>(const std::string& l, fxcc::graph::common::Texture3DMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_Texture3Ds.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_Texture3Ds)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::BRDFTextureMap>(const std::string& l, fxcc::graph::common::BRDFTextureMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_BRDF_LUT_Maps.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_BRDF_LUT_Maps)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}

	ImGui::Image(e.GetTextureId(), { 100,100 });

	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}

template<>
bool Editor::Edit<fxcc::graph::common::IrradianceTextureMap>(const std::string& l, fxcc::graph::common::IrradianceTextureMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_IrradianceMaps.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_IrradianceMaps)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::PrefilterTextureMap>(const std::string& l, fxcc::graph::common::PrefilterTextureMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : TextureImporter::m_TextureMetaData.m_TextureMetaCaches)
		{
			if (value.m_PrefilterMaps.empty())continue;

			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_PrefilterMaps)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}
	if (flag)
	{
		e.OnLoad();
	}
	return flag;
}

template <>
bool Editor::Edit(const std::string& label, TextureMaps& inst)
{
    bool flag{ 0 };

    int index = 0;

    for (auto& it : inst.m_Texture2Ds)
    {
        flag |= EditInst<fxcc::graph::common::Texture2DMap>(it.first, it.second);
    }


    return flag;
}
